﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;

namespace Lesson6_泛型约束
{
    class Fun<K>
    {

    }
    

    class Text<T> where T :struct
    {
        public T value;

        public void Fun<K>(K k) where K : struct    //struct 值类型约束
        {

        }
    }

    class Text1<T> where T : class   //  where 泛型字母 :class 引用类型约束
    {
        public T value;

        public void Fun<T>(T t) where T : class
        {

        }

    
    }
    class Text2<T> where T : class   //  where 泛型字母 :class 引用类型约束
    {


    }

     class Text3<T> where T : new()   //  where 泛型字母 :new() 无参构造函数约束
    {
        public T value;

        public void Fun<T>(T t) where T : new()
        {

        }


    }
    class Text1    //无参构造函数
                   //有默认值
    { 

    }
    class Text2:Text1
    {
        public  Text2(int i)   //有参构造函数

        {

        }
    }

    class Text5:IFly
    { 
    
    }


    class Text4<T> where T : Text1
    {

    }

    interface IFly
    { }
    interface IRun:IFly
    {

    }
    class Text7<T> where T :IFly   //  where  :IFly 接口约束(某个接口的派生类型)
    {
        public T value;

        public void Fun<T>(T t) where T : IFly
        {

        }


    }

    class Text9<K,U> where K : U
    {
    public K value; 
    public void Fun<T,V>(T t) where T : V
        { }
    }

    #region 知识点三 约束的组合使用   不同泛型约束类型之间用逗号隔开

    class Text7<T, U> where T : class ,new() //  where  :IFly 接口约束(某个接口的派生类型)
    {
        public T value;

        public void Fun<T>(T t) where T : class , new()
        {

        }


    }
    #endregion

    #region 不同泛型有约束
    class Text10<T, U> where T : class, new() where U :struct
    {
        public T value;

        public void Fun<T>(T t) where T : class, new()
        {

        }


    }
    #endregion
    internal class Program
    {
        static void Main(string[] args)
        {
            #region 知识点一 什么是泛型约束 
            //让泛型的字符有一定的约束条件
            //关键字:where
            //语法格式    where 泛型字母:（约束的类型）
            #endregion
            #region 知识点二 各泛型约束讲解
            #region 值类型约束
            Text<int> t = new Text<int>();

            t.Fun<float>(1.2f);
            #endregion

            #region   引用类型 where 泛型字母 :class 引用类型约束

            Text1<Random> r = new Text1<Random>();
            r.value = new Random();

            r.Fun<object>(new object());
            /* Text2<int> i = new Text2<int>();*/   //会报错的原因是泛型约束此类型为引用类型
            #endregion

            #region 公共 无参 构造函数非抽象类型约束   where 泛型字母 :new() 无参构造函数约束
            Text3<Text1> t1 = new Text3<Text1>();   //公共无参构造函数
            /*  Text3<Text2> t2 = new Text3<Text2>();*/   //泛型约束为无参所以会报错
            Text<int> t3 = new Text<int>();   //所有的值类型(struct)都默认有一个无参构造函数
            #endregion


            #region 某个类本身或其派生类   where 泛型字母:类本身或其派生类 引用类型约束
            Text4<Text1> t4 = new Text4<Text1>();   //不会报错

            Text4<Text2> t5 = new Text4<Text2>();   //不会报错，是因为Text2是Text1的派生类

            /*   Text4<Text5> t6 = new Text4<Text5>();   *///会报错，因为Text5不是Text1的派生类

            /* Text4<object> t7 = new Text4<object>(); */  //不会报错，因为object是所有类的基类  一定是类本身或其派生类
            #endregion


            #region  接口类  where  :接口类 接口约束(某个接口的派生类型)
            Text7<IFly> t8 = new Text7<IFly>();   //不会报错，因为Text5是IFly的派生类   
            t8.value = new Text5();
            Text7<Text5> t9 = new Text7<Text5>();   //不会报错，因为Text5是IFly的派生类
            #endregion


            #region   另一个泛型类本身或其派生字母  where 泛型字母:另一个泛型类本身或其派生字母 



            #endregion



            #region 知识点三 约束的组合使用
            #endregion

            #region  不同泛型约束

            #endregion

            
            #region 总结
            //1:可以组合使用
            //2：多个泛型约束，用where 连接即可
            #endregion
           
        }
    }
}
#endregion